/**   
 * 项目名：化工企业安全生产信息化管理平台
 * 日期：    2020-06-28 02:01:43  
 * Copyright (c) 2015- -版权所有     
 */

package com.joysuch.wwyt.audit.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.transaction.Transactional;

import com.joysuch.wwyt.audit.bean.AuditLogActionDefDetailBean;
import com.joysuch.wwyt.audit.bean.AuditLogActionDefEditBean;
import com.joysuch.wwyt.audit.bean.AuditLogActionDefListBean;
import com.joysuch.wwyt.audit.bean.AuditLogActionDefListBean.SearchAuditLogActionDef;
import com.joysuch.wwyt.audit.entity.AuditLogActionDef;
import com.joysuch.wwyt.audit.entity.dsl.QAuditLogActionDef;
import com.joysuch.wwyt.audit.repository.AuditLogActionDefDao;
import com.joysuch.wwyt.audit.service.AuditLogActionDefService;
import com.joysuch.wwyt.core.common.util.PageDataUtils;
import com.joysuch.wwyt.core.common.util.PageDataUtils.PageDataConvert;
import com.joysuch.wwyt.core.exception.BusinessRestrictionsException;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

@Service
@Transactional
public class AuditLogActionDefServiceImpl implements AuditLogActionDefService {

    @Autowired
    private AuditLogActionDefDao dao;
    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    private Map<String, AuditLogActionDef> cache;

    @Override
    public AuditLogActionDef add(AuditLogActionDefEditBean entity) {
        AuditLogActionDef content = new AuditLogActionDef();
        // if (StringUtils.isNotBlank(entity.getCode())) {
        // Assert.isTrue(dao.countOfCode(entity.getCode()) == 0, String.format("编号%s已经存在", entity.getCode()));
        // content.setCode(entity.getCode());
        // } else {
        // content.setCode(bizCodeGeneratorFacade.shenJiRiZhi());
        // }
        BeanUtils.copyProperties(entity, content, "id", "code");
        dao.save(content);
        return content;
    }

    @Override
    public void update(AuditLogActionDefEditBean entity) {
        AuditLogActionDef content = dao.findById(entity.getId()).get();
        Assert.notNull(entity.getCode(), "编号不能为空");
        Assert.isTrue(dao.countOfCodeExcludeId(entity.getCode(), entity.getId()) == 0,
                String.format("编号%s已经存在", entity.getCode()));
        content.setCode(entity.getCode());
        BeanUtils.copyProperties(entity, content, "id", "code");
        dao.save(content);
    }

    @Override
    public Page<AuditLogActionDefListBean> findByPage(Pageable page, SearchAuditLogActionDef condition) {
        Predicate predicate = prepareListSearchCondition(condition);

        Page<AuditLogActionDef> data = predicate == null ? dao.findAll(page) : dao.findAll(predicate, page);

        return PageDataUtils.convertPageData(data, new PageDataConvert<AuditLogActionDefListBean, AuditLogActionDef>() {

            @Override
            public AuditLogActionDefListBean convert(AuditLogActionDef f) {
                AuditLogActionDefListBean bean = new AuditLogActionDefListBean();
                BeanUtils.copyProperties(f, bean);
                return bean;
            }

        });
    }

    private Predicate prepareListSearchCondition(SearchAuditLogActionDef condition) {
        Predicate p = null;
        QAuditLogActionDef q = QAuditLogActionDef.auditLogActionDef;
        if (condition.getCode() != null) {
            p = ExpressionUtils.and(p, q.code.contains(condition.getCode()));
        }
        if (condition.getName() != null) {
            p = ExpressionUtils.and(p, q.name.contains(condition.getName()));
        }
        if (condition.getModule() != null) {
            p = ExpressionUtils.and(p, q.module.eq(condition.getModule()));
        }
        if (condition.getOperationName() != null) {
            p = ExpressionUtils.and(p, q.operationName.contains(condition.getOperationName()));
        }
        if (condition.getTriggerType() != null) {
            p = ExpressionUtils.and(p, q.triggerType.eq(condition.getTriggerType()));
        }
        if (condition.getTriggerValue() != null) {
            p = ExpressionUtils.and(p, q.triggerValue.eq(condition.getTriggerValue()));
        }
        if (condition.getGroupId() != null) {
            p = ExpressionUtils.and(p, q.groupId.eq(condition.getGroupId()));
        }
        if (condition.getGroupOrder() != null) {
            p = ExpressionUtils.and(p, q.groupOrder.eq(condition.getGroupOrder()));
        }
        if (condition.getResultJudgeType() != null) {
            p = ExpressionUtils.and(p, q.resultJudgeType.eq(condition.getResultJudgeType()));
        }
        if (condition.getResultJudgeRule() != null) {
            p = ExpressionUtils.and(p, q.resultJudgeRule.eq(condition.getResultJudgeRule()));
        }
        if (condition.getOpObjectType() != null) {
            p = ExpressionUtils.and(p, q.opObjectType.eq(condition.getOpObjectType()));
        }
        if (condition.getQueryObjectMethod() != null) {
            p = ExpressionUtils.and(p, q.queryObjectMethod.eq(condition.getQueryObjectMethod()));
        }
        if (condition.getQueryObjectParams() != null) {
            p = ExpressionUtils.and(p, q.queryObjectParams.eq(condition.getQueryObjectParams()));
        }
        if (condition.getState() != null) {
            p = ExpressionUtils.and(p, q.state.eq(condition.getState()));
        }
        if (condition.getDescription() != null) {
            p = ExpressionUtils.and(p, q.description.eq(condition.getDescription()));
        }
        return p;
    }

    @Override
    public void delete(Long id) throws BusinessRestrictionsException {
        // 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用。不能删除时将抛出业务异常
        checkBussinessRestrictions(id);
        dao.deleteById(id);
    }

    /**
     * 校验业务逻辑是否允许删除。如本数据被其他业务关联，删除后导致其他业务不可用
     * 
     * @param id
     *            要删除的业务ID
     * @throws BussinessRestrictionsException
     *             抛出的业务异常
     */
    private void checkBussinessRestrictions(Long id) throws BusinessRestrictionsException {
    }

    @Override
    public AuditLogActionDef findById(Long id) {
        return dao.findById(id).orElse(null);
    }

    @Override
    public AuditLogActionDefDetailBean getById(Long id) {
        AuditLogActionDef entity = findById(id);
        if (entity == null) {
            return null;
        }
        AuditLogActionDefDetailBean bean = new AuditLogActionDefDetailBean();
        BeanUtils.copyProperties(entity, bean);
        return bean;
    }

    @Override
    public List<AuditLogActionDef> loadAll() {
        cache = new HashMap<String, AuditLogActionDef>();
        List<AuditLogActionDef> all = dao.findAll();
        for (AuditLogActionDef d : all) {
            cache.put(createKey(d), d);
        }
        System.err.println("从数据库中加载 " + all.size() + "条规则");
        return all;
    }

    private String createKey(AuditLogActionDef d) {
        return createKey(d.getTriggerType(), d.getTriggerValue());
    }

    private String createKey(String triggerType, String triggerValue) {
        return triggerType + "_" + triggerValue;
    }

    @Override
    public void reload() {
        if (cache != null) {
            cache.clear();
        }
        loadAll();
    }

    @Override
    public AuditLogActionDef findOneByTriggerTypeAndValue(String triggerType, String value) {
        return cache.get(createKey(triggerType, value));
    }

}
